package com.apache.security.filter;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.apache.security.SecurityFilter;
import com.apache.tools.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SqlCookieFilter implements SecurityFilter {

	private Logger log = LoggerFactory.getLogger(SqlCookieFilter.class);
	private String[] inj_str = { "select ", "(select", "insert ", "drop ", "union ", "delete ", "update ", "+and+",
			" and ", "+or+", " or ", "'='", "<script", "confirm(", "prompt(", "eval(", "function(", "alert(", ":alert",
			"ltrim(", "[window[", "<iframe", "<a href", "<input ", "<img", "<audio", "onerror\\=", "ltrim(",
			"{tostring:", "</script", "</style", "href=" };//过滤掉的sql关键字，可以手动添加
	private Pattern p;
	private Matcher m;
	private String errorPage;

	public int doFilterInvoke(HttpServletRequest request, HttpServletResponse response) throws IOException,
			ServletException {
		//获得所有请求参数名  
		boolean mark = checkSecurity(request);
		if (mark) {
			response.sendRedirect(request.getContextPath() + "/" + errorPage);
			return FAILURE;
		}
		/*if (StrUtil.isNotNull(sql)) {
			log.info("当前请求参数:" + sql);
			if (sql_inj(sql.toLowerCase())) {
				response.sendRedirect(request.getContextPath() + "/" + errorPage);
				return FAILURE;
			}
		}*/
		return SUCCESS;
	}

	/*public boolean sql_inj(String str) {
		String[] badStrs = inj_str.split("\\|");
		for (int i = 0; i < badStrs.length; i++) {
			if (str.indexOf(badStrs[i]) >= 0) {
				return true;
			}
		}
		return false;
	}*/

	public void setErrorPage(String errorPage) {
		this.errorPage = errorPage;
	}

	protected void sendErrorPage(HttpServletRequest request, HttpServletResponse response) {
		String header = request.getHeader("X-Requested-With");
		boolean isAjax = "XMLHttpRequest".equals(header) ? true : false;
		try {
			if (isAjax) {//ajax请求
				response.setContentType("text/html;charset=utf-8");
				PrintWriter writer = response.getWriter();
				writer.write("{\"flag\":\"F\",\"msg\":\"非法请求\"}");
				writer.flush();
				writer.close();
			} else {//正常请求
				request.setAttribute("errors", "非法请求");
				//	response.sendRedirect(request.getContextPath() + "/common/error.jsp");
				request.getRequestDispatcher("/common/error.jsp").forward(request, response);
			}
		} catch (Exception e) {
		}
	}

	/**
	 * description:  安全验证
	 * @return   不通过：true;反之为false;
	 */
	protected boolean checkSecurity(HttpServletRequest request) {
		String pui = request.getRequestURI();
		if (pui.toLowerCase().contains("/owa_util.signature") || pui.toLowerCase().contains("/sqlnet.trc")) {
			log.warn("非法请求参数=" + pui);
			return true;
		}
		if (StrUtil.isNotNull(request.getParameter("formToken"))) {
			return false;
		}
		String str = request.getQueryString();
		if (StrUtil.isNull(str)) {
			Enumeration<String> params = request.getParameterNames();//获得所有请求参数名  
			while (params.hasMoreElements()) { //得到参数名
				String name = params.nextElement();
				String[] value = request.getParameterValues(name);
				for (int i = 0; i < value.length; i++) {
					str = str + value[i];
				}
			}
		}
		if (StrUtil.isNull(str))
			return false;
		String sql = str.toLowerCase();
		sql = sql.replace("%28", "(").replace("%2b", "+").replace("%3c", "<").replace("%27", "'").replace("%5b", "[")
				.replace("%5d", "]").replace("%3d", "=").replace("%7c", "|").replace("%7b", "{").replace("%3a", ":")
				.replace("%2f", "/");
		for (int i = 0; i < inj_str.length; i++) {
			if (sql.indexOf(inj_str[i]) >= 0) {
				log.warn("非法请求参数=" + sql);
				return true;
			}
		}
		return isEqualString(str);
	}

	private boolean isEqualString(String str) {
		String regEx_style = "(<[a-zA-Z].*?>)|(<[\\/][a-zA-Z].*?>)";
		p = Pattern.compile(regEx_style);
		m = p.matcher(str);
		return m.matches();
	}

}
